package com.idroc.storage.support;

import com.idroc.storage.IoBlock;
import com.idroc.storage.IoBlockFile;
import com.idroc.storage.IoPage;
import com.idroc.storage.IoPageIdUtil;

/**
 * 文件IO分页
 * @author yuyoo (yuyoo4j@163.com)
 * @date 2010-3-27 下午05:07:11
 */
public class FileIoPage implements IoPage {
	
	/**
	 * 默认文件IO分页头大小
	 */
	public static int FILE_IOPAGE_HERDER_SIZE = 4;
	 		
	/**
	 * IO块
	 */
	protected IoBlock block = null;
	
	/**
	 * IO分页ID
	 */
	protected long pageId = 0;
	
	/**
	 * IO分页类型
	 */
	protected short pageType = 0;
	
	/**
	 * IO块文件ID
	 */
	protected short fileId = 0;
	
	/**
	 * IO块在文件中的编号
	 */
	protected long blockIndex = 0;
	
	/**
	 * 文件IO分页头大小
	 */
	protected int headerSize = 0;
	
	/**
	 * 构建一个文件IO分页
	 * @param pageId -- IO分页ID
	 * @param headerSize -- IO分页头大小
	 * @param block -- IO分页使用的IO块
	 */
	public FileIoPage(long pageId, int headerSize, IoBlock block) {
		
		initialize(pageId, headerSize, block);
	}
	
	/**
	 * 构建一个文件IO分页
	 * @param pageId -- IO分页ID
	 * @param block -- IO分页使用的IO块
	 */
	public FileIoPage(long pageId, IoBlock block) {
		
		initialize(pageId, FILE_IOPAGE_HERDER_SIZE, block);
	}
	
	/**
	 * 初始化
	 * @param pageId --  IO分页ID
	 * @param headerSize -- IO分页头大小
	 * @param block -- IO分页使用的IO块
	 */
	protected void initialize(long pageId, int headerSize, IoBlock block) {
		
		this.pageId = pageId;
		this.headerSize = headerSize;
		this.block = block;
		this.pageType = IoPageIdUtil.getPageType(pageId);
		this.fileId = IoPageIdUtil.getFileId(pageId);
		this.blockIndex = IoPageIdUtil.getIoBlockIndex(pageId);
	}
	
	
	public IoBlock getIoBlock() {

		return block;
	}

	public long getNext() {

		return block.readLong(0);
	}

	public long getPageId() {

		return pageId;
	}

	public void setNext(long pageId) {

		block.writeLong(0, pageId);
	}

	public int bodySize() {
		
		return block.size() - headerSize;
	}

	public int headerSize() {

		return headerSize;
	}

	public byte readBody(int pos) {
		
		return block.read(headerSize + pos);
	}

	public byte[] readBodyBytes(int pos, int length) {
		 
		return block.readBytes(headerSize + pos, length);
	}

	public int readBodyInt(int pos) {
		 
		return block.readInt(headerSize + pos);
	}

	public long readBodyLong(int pos) {
		 
		return block.readLong(headerSize + pos);
	}

	public short readBodyShort(int pos) {
		 
		return block.readShort(headerSize + pos);
	}

	public int size() {
		 
		return block.size();
	}

	public void writeBody(int pos, byte value) {
		 
		block.write(headerSize + pos, value);
	}

	public void writeBodyBytes(int pos, byte[] values) {
		 
		block.write(headerSize + pos, values);
	}

	public void writeBodyInt(int pos, int value) {
		
		 block.writeInt(headerSize + pos, value);
	}

	public void writeBodyLong(int pos, long value) {

		block.writeLong(headerSize + pos, value);
	}

	public void writeBodyShort(int pos, short value) {

		block.writeShort(headerSize + pos, value);
	}

	public short getFileId() {
		
		return fileId;
	}

	public long getIoBlockIndex() {

		return blockIndex;
	}

	public short getPageType() {

		return pageType;
	}

}
